#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <mutex>

using namespace std;

//1.设计一个类，无法被拷贝
//class test
//{
//	test(int n)
//		:num(n)
//	{}
//
//	//C++11直接删除拷贝构造
//	test(const copyobj& copy) = delete;
//
//private:
//	//test(const copyobj& copy); //C++98声明为私有
//
//	int num;
//};


//2.设计只能在堆上创建的类
//两种方案， 只封印构造 留下一个静态的构造  或   只封印析构，留下一个静态的析构
//class test
//{
//public:
//	//static test* Create(int n) { return new test(n); }
//	test(int n)
//		:num(n)
//	{}
//
//	void Destory()
//	{
//		delete this;
//	}
//
//	
//	test(const test&) = delete; //禁用拷贝构造
//	test& operator=(const test&) = delete; //禁用赋值重载
//	//~test() {}
//
//private:
//
//	//test& operator=(const test&) {}
//	//test(const test& t) {}
//
//	~test() {}
//
//	int num;
//};

//int main()
//{
//	//test* t = test::Create(1);
//
//	test* t = new test(1);
//	t->Destory();
//	return 0;
//}


//3.设计只能在栈上创建对象的类
//两个办法，封印构造函数提供一个静态方法构造栈上对象，
//class test
//{
//public:
//	static test Create(int n) { return test(n); }
//	
//	test(test&& t)
//		:num(t.num)
//	{}
//
//private:
//	test(int n)
//		:num(n)
//	{}
//
//	test(const test&) = delete;
//	test& operator=(const test&) = delete;
//
//	int num;
//};
//
//int main()
//{
//	test t = test::Create(1);
//	//static test st = t;
//	test st = move(t);
//	return 0;
//}

//4.设计不能被继承的类
//class testbase
//{
//public:
//
//private:
//	testbase(int n)
//		:num(n)
//	{}
//
//	int num;
//};

//class testbase final
//{
//public:
//
//private:
//
//	int num;
//};

//class test :public testbase
//{
//public:
//	test() = default;
//
//private:
//	int n;
//};
//
//int main()
//{
//	test t();
//	return 0;
//}



//5.单例模式
//饿汉模式
//class Singleton
//{
//public:
//	//static Singleton *const  GetInstance()
//	//{
//	//	return _ins;
//	//}
//	int num;
//	static Singleton* const  _ins;
//
//private:
//	// 限制类外面随意创建对象
//	Singleton()
//	{}
//
//private:
//	//static Singleton* const  _ins;
//
//};
//
//Singleton* const  Singleton::_ins = new Singleton;
//
//int main()
//{
//	//Singleton::GetInstance()->num = 0;
//	//cout << Singleton::GetInstance()->num << endl;
//	//Singleton::GetInstance()->num = 1;
//	//cout << Singleton::GetInstance()->num << endl;
//	
//	Singleton::_ins->num = 0;
//	cout << Singleton::_ins->num << endl;
//	Singleton::_ins->num = 1;
//	cout << Singleton::_ins->num << endl;
//
//
//	return 0;
//}


//懒汉模式
//class Singleton
//{
//public:
//	static Singleton* GetCreate()
//	{
//		if (!_ins) //先检查 避免申请锁和解锁影响性能
//		{
//			_m.lock(); //加锁 防止多线程重复new
//			if (!_ins) //双检查加锁
//			{
//				_ins = new Singleton;
//			}
//			_m.unlock();
//		}
//		return _ins;
//	}
//
//	void Destory() //特殊场景下需要手动释放
//	{
//		_m.lock(); //加锁 防止多线程重复new
//		if (_ins)
//		{
//			delete _ins;
//			_ins = nullptr;
//		}
//		_m.unlock();
//	}
//
//	struct GC //垃圾回收器
//	{
//		~GC() 
//		{
//			if(_ins)
//				_ins->Destory();
//		}
//	};
//
//	int num;
//
//private:
//	Singleton() {} //限制内外随便创建对象
//private:
//	static Singleton* _ins; //对象指针
//	static mutex _m; //锁
//	static GC _gc; //自动回收器 - 内部类
//};
//
//Singleton* Singleton::_ins = nullptr;
//mutex Singleton::_m;
//Singleton::GC Singleton::_gc;
//
//int main()
//{
//	Singleton::GetCreate()->num = 0;
//	cout << Singleton::GetCreate()->num << endl;
//	Singleton::GetCreate()->num = 1;
//	cout << Singleton::GetCreate()->num << endl;
//	Singleton::GetCreate()->Destory();
//	Singleton::GetCreate()->num = 3;
//	cout << Singleton::GetCreate()->num << endl;
//
//	return 0;
//}